<?php
declare(strict_types=1);

namespace SixShop\Lakala\Entity;

use SixShop\Core\Entity\BaseEntity;
use SixShop\Core\Exception\LogicException;
use SixShop\Lakala\Enum\ReceiverActionEnum;
use SixShop\Lakala\Enum\UploadFileTypeEnum;
use SixShop\Lakala\Facade\Config;
use SixShop\Lakala\Enum\ProfitShareOrderStatusEnum;
use SixShop\Lakala\Enum\ReceiverStatusEnum;
use SixShop\Lakala\Facade\LedgerService;
use SixShop\Lakala\Facade\MMSService;
use SixShop\Lakala\Model\ProfitShareReceiverModel;
use think\db\Query;
use think\facade\Db;
use think\Model;
use think\Paginator;
use function SixShop\Core\throw_logic_exception;

/**
 * @mixin ProfitShareReceiverModel
 */
class ProfitShareReceiverEntity extends BaseEntity
{
    public function saveReceiver(array $data): self
    {
        /* @var self $entity */
        $entity = $this->where(['user_id' => $data['user_id']])->findOrEmpty();
        if (!$entity->isEmpty()) {
            throw_logic_exception('已存在分账接收方申请记录，请勿重复提交！');
        }
        $entity->data($data);
        Db::transaction(function () use ($entity) {
            $entity->action = ReceiverActionEnum::ADD;
            $entity->status = ReceiverStatusEnum::PENDING;
            $entity->save();
            $result = MMSService::cardBin($entity->order_no, $entity->acct_no, $entity->org_code);
            $entity->acct_open_bank_code = $result->bankCode;
            $entity->acct_clear_bank_code = $result->clearingBankCode;
            $entity->save();
        });

        return $entity;
    }

    public function getReceiverList(array $params, array $pageAndLimit): Paginator
    {
        return $this->withSearch(['order_no', 'status', 'user_id'], $params)
            ->with(['user' => function (Query $query) {
                $query->field(['id', 'nickname', 'avatar', 'username', 'mobile']);
            }])
            ->append(['action_text','status_text'])
            ->order('id', 'desc')
            ->paginate($pageAndLimit);
    }

    public function getReceiver(array $params): self
    {
        $entity = $this->where($params)
            ->append(['action_text','status_text'])
            ->findOrEmpty();
        if ($entity->isEmpty()) {
            throw_logic_exception('分账接收方申请记录不存在！');
        }
        if ($entity->receiver_no && $entity->status == ReceiverStatusEnum::SUBMITTING) {
            $response = LedgerService::queryReceiverDetail($entity->order_no, $entity->receiver_no, $entity->org_code);
            if ($response->rowStatus == 'VALID') {
                $entity->status = ReceiverStatusEnum::VERIFIED;
                $entity->wallet_id = $response->walletId;
            }
            $entity->save();
        }
        if ($entity->status == ReceiverStatusEnum::BINDING) {
            $response = LedgerService::queryBindApplyList([
                'orderNo' => $entity->order_no,
                'orgCode' => $entity->org_code,
                'receiverNo' => $entity->receiver_no,
            ]);
            if (isset($response->list[0])
                && $response->list[0]->rowSno == $entity->order_no) {
                $entity->status = match ($response->list[0]->auditStatus) {
                    '0' => ReceiverStatusEnum::BINDING,
                    '1' => ReceiverStatusEnum::BOUND,
                    '2' => ReceiverStatusEnum::BIND_FAILED
                };
                if ($entity->status == ReceiverStatusEnum::BOUND) {
                    $entity->effective_time = date('Y-m-d H:i:s');
                }
                $entity->fail_reason = $response->list[0]->remark;
                $entity->save();
            }
        }
        return $entity;
    }

    public function apply(int $id): self
    {
        $entity = $this->getReceiver(['id' => $id]);
        if ($entity->status != ReceiverStatusEnum::PENDING || $entity->action != ReceiverActionEnum::ADD) {
            throw_logic_exception('待审核状态新增记录才可以申请！');
        }
        $reqData = [
            'orderNo' => $entity->order_no,
            'orgCode' => $entity->org_code,
            'receiverName' => $entity->receiver_name,
            'contactMobile' => $entity->contact_mobile,
            'acctNo' => $entity->acct_no,
            'acctName' => $entity->acct_name,
            'acctTypeCode' => $entity->acct_type_code,
            'acctCertificateType' => $entity->acct_certificate_type,
            'acctCertificateNo' => $entity->acct_certificate_no,
            'acctOpenBankCode' => $entity->acct_open_bank_code,
            'acctOpenBankName' => $entity->acct_open_bank_name,
            'acctClearBankCode' => $entity->acct_clear_bank_code,
        ];
        try {
            $response = LedgerService::applyLedgerReceiver($reqData);
        } catch (LogicException $e) {
            if ($e->getResponse()->getData()['code'] == 103001) {
                // 系统异常，请稍后重试
                // 创建新的申请记录
                $newEntity = $entity->clone()->toArray();
                unset($newEntity['id'], $newEntity['order_no']);
                $this->save($newEntity);
                $entity->delete();
            }
            throw $e;
        }
        $entity->org_id = $response->orgId;
        $entity->org_name = $response->orgName;
        $entity->receiver_no = $response->receiverNo;
        $entity->status = ReceiverStatusEnum::SUBMITTING;
        $entity->save();
        return $entity;
    }

    public function bind(int $id): self
    {
        $entity = $this->getReceiver(['id' => $id]);
        if ($entity->status != ReceiverStatusEnum::VERIFIED || $entity->action != ReceiverActionEnum::ADD) {
            throw_logic_exception('验证通过状态新增记录才可以绑定！');
        }
        if (!$entity->entrust_file_path) {
            if (!$entity->entrust_local_path) {
                // 添加默认合作协议
                $defaultReceiverAgreementFile = Config::getConfig('receiver_agreement_file');
                if (!$defaultReceiverAgreementFile) {
                    throw_logic_exception('请先添加默认合作协议！');
                }
                $entity->entrust_local_path = Config::getConfig('receiver_agreement_file')[0];
                $entity->save();
            }
            // 上传协议文件
            $entrustLocalPath = public_path() . $entity->entrust_local_path;
            $pathInfo = pathinfo($entrustLocalPath);
            $response = MMSService::uploadFile(
                orderNo: $entity->order_no,
                attType: UploadFileTypeEnum::SPLIT_COOPERATION_FILE,
                attExtName: $pathInfo['extension'],
                fileContent: file_get_contents($entrustLocalPath),
            );
            $entity->entrust_file_name = '合作协议.' . $pathInfo['extension'];
            $entity->entrust_file_path = $response->attFileId;
            $entity->save();
        }
        $respData = LedgerService::applyBind([
            'orderNo' => $entity->order_no,
            'orgCode' => $entity->org_code,
            'receiverNo' => $entity->receiver_no,
            'entrustFileName' => $entity->entrust_file_name,
            'entrustFilePath' => $entity->entrust_file_path,
        ]);
        $entity->mer_cup_no = $respData['merCupNo'];
        $entity->status = ReceiverStatusEnum::BINDING;
        $entity->save();
        return $entity;
    }

    public function updateReceiver(array $params, array $data):self
    {
        /* @var self $entity */
        $entity = $this->where($params)->findOrEmpty();
        if ($entity->isEmpty()) {
            throw_logic_exception('分账接收方申请记录不存在！');
        }
        $saveData = $entity->toArray();
        unset($saveData['id'], $saveData['order_no'], $saveData['create_time'], $saveData['effective_time']);
        $saveData = array_merge($saveData, $data);
        $this->data($saveData);
        Db::transaction(function () use ($entity) {
            $this->action = ReceiverActionEnum::UPDATE;
            $this->status = ReceiverStatusEnum::PENDING;
            $this->save();
            $result = MMSService::cardBin($this->order_no, $this->acct_no, $this->org_code);
            $this->acct_open_bank_code = $result->bankCode;
            $this->acct_clear_bank_code = $result->clearingBankCode;
            $this->fail_reason = '';
            $this->save();
        });
        return  $this;
    }

    public function modify(int $id): self
    {
        $entity = $this->where(['id' => $id])
            ->append(['action_text','status_text'])
            ->findOrEmpty();
        if ($entity->isEmpty()) {
            throw_logic_exception('分账接收方申请记录不存在！');
        }
        $reqData = [
            'orderNo' => $entity->order_no,
            'orgCode' => $entity->org_code,
            'receiverNo' => $entity->receiver_no,
            'receiverName' => $entity->receiver_name,
            'contactMobile' => $entity->contact_mobile,
            'acctNo' => $entity->acct_no,
            'acctTypeCode' => $entity->acct_type_code,
            'acctOpenBankCode' => $entity->acct_open_bank_code,
            'acctOpenBankName' => $entity->acct_open_bank_name,
            'acctClearBankCode' => $entity->acct_clear_bank_code,
        ];
        $response = LedgerService::modifyLedgerReceiver($reqData);
        if ($response->receiverNo == $entity->receiver_no) {
            $entity->status = ReceiverStatusEnum::BOUND;
            $entity->effective_time = date('Y-m-d H:i:s');
            $entity->save();
        }
        return $entity;
    }
}